// $Id: FileIO.cpp 86 2007-11-12 15:49:26Z bram $


/**
 * FileIO class definition.
 *
 * @file FileIO.cpp
 * @author Wim Leers
 */


#include "FileIO.h"
#include "InternalException.h"


//----------------------------------------------------------------------------
// Public methods.

/**
 * Open (en lees uit) een bestand.
 */
void FileIO::Open(void) {
	ifstream fs(m_fileName.c_str(), ios::in);
	FILEIO_ROW row;

	// Zorg dat de tabel leeg is.
	m_table.erase(m_table.begin(), m_table.end());

	if (fs.is_open()) {
		while (!fs.eof()) {
			switch (m_format) {
				case FORMAT_CSV:
					row = csvReadRow(fs);
					if (row.size())
						m_table.push_back(row);
					break;
			}
		}
		fs.close();
	}
}

/**
 * Sla een bestand op.
 */
void FileIO::Save(void) {
	ofstream fs(m_fileName.c_str(), ios::out);
	FILEIO_ROW row;
	FILEIO_TABLE::iterator it;

	if (fs.is_open()) {
		switch (m_format) {
			case FORMAT_CSV:
				for (it = m_table.begin(); it != m_table.end(); it++)
					cvsWriteRow(fs, *it);
				break;
		}
		fs.close();
	}
	else {
	  InternalException e(
	    "FileIO::Open()",
	    "Het bestand " + m_fileName + " kon niet geopend worden om te schrijven."
    );
    throw(e);
	}

}

/**
 * Wis het bestand.
 */
void FileIO::Erase(void) {
	// Wis de tabelvoorstelling van het bestand in het geheugen.
	m_table.erase(m_table.begin(), m_table.end());

	// Wis het bestand zelf.
	ofstream f(m_fileName.c_str(), ios::trunc);
	f.close();
}


//----------------------------------------------------------------------------
// Private methods.

/**
 * Leest een rij van strings uit een filestream.
 *
 * @param fs
 *   Filestream die geopend is in leesmodus.
 * @param row
 *   Een rij van strings.
 */
FILEIO_ROW FileIO::csvReadRow(ifstream & fs) {
	string line;
	unsigned int pos = 0, prevPos = 0;
	FILEIO_ROW row;

	// Lees de volgende rij (één regel) van het bestand in.
	getline(fs, line);

	// Plaats alle velden in deze rij in een queue.
	while (line.length() > 0 && pos < line.npos) {
		// Negeer de komma.
		if (pos > 0)
			prevPos = pos + 1;

		pos = line.find(',', prevPos);
		row.push_back(line.substr(prevPos, pos - prevPos));
	}
	return row;
}

/**
 * Schrijft een rij van strings naar een filestream.
 *
 * @param fs
 *   Filestream die geopend is in schrijfmodus.
 * @param row
 *   Een rij van strings.
 */
void FileIO::cvsWriteRow(ofstream & fs, FILEIO_ROW row) {
	FILEIO_ROW::iterator it, test;

	for (it = row.begin(); it != row.end(); it++) {
		fs << *it;

		// Test of we nog niet aan de laatste kolom zitten, en print een komma
		// als dat inderdaad nog niet zo is.
		test = it;
		test++;
		if (test != row.end())
			fs << ',';
	}
	fs << endl;
}
